﻿# coding: utf-8

import ToolRotation
import Transformation
import SceneNode

from History.CmdRotation import CCmdRotation
from History.CmdGroupCommand import CCmdGroupCommand
from InputHandler import CInputHandler

class CRotationTool(CInputHandler):
    def __init__(self):
        """ Default class constructor """
        
        self._handle = 0
        self._yaw = 0
        self._pitch = 0
        self._roll = 0
        self._groupCmdRef = None
        
    def Create(self):
        """ Create rotation tool """
        
        self._handle = ToolRotation._New()
        ToolRotation.Enable(self._handle, False)
        
    def Destroy(self):
        """ Destroy rotation tool """
        
        ToolRotation._Delete(self._handle)
        
    def OnEnter(self, **p):
        """ Enter the rotation state """
        
        for ref in SCENE_EDITOR._selectedObjectRefList:
            node = ref()
            if node:
                ToolRotation.Enable(self._handle, True)
                self.ResetPosition()
                return
                
        ToolRotation.Enable(self._handle, False)
        SCENE_EDITOR._selectedObjectRefList = []
        
    def ResetPosition(self):
        """ Calculate the center of all selected objects """
        i = 0
        x, y, z = 0, 0, 0
        for ref in SCENE_EDITOR._selectedObjectRefList:
            node = ref()
            if not node:
                continue
                
            tx, ty, tz = Transformation.GetRelativeTranslation(SceneNode._CTransformation(node.GetCoreHandle()))
            x, y, z = x + tx, y + ty, z + tz
            
            i += 1
        
        if i > 0:
            x, y, z = x / i, y / i, z / i
            ToolRotation.SetPosition(self._handle, x, y, z)
            ToolRotation.Enable(self._handle, True)
        else:
            ToolRotation.Enable(self._handle, False)
            SCENE_EDITOR._selectedObjectRefList = []
        
    def OnExit(self):
        ToolRotation.Enable(self._handle, False)
        
    def Update(self):
        ToolRotation.Update(self._handle)

        try:
            groupCmd = self._groupCmdRef()
        except:
            return
            
        y, p, r = ToolRotation.GetRotation(self._handle)
        dy, dp, dr = y - self._yaw, p - self._pitch, r - self._roll
        for cmd in groupCmd._paramDict['cmdList']:
            cmd.UpdateRotation(dy, dp, dr)
        
    def Render(self):
        """ Render transform tool """
        
        ToolRotation.Render(self._handle)
        
    def OnMouseLeftDown(self, e):
        """ Process mouse left down message """
        
        x, y = e.GetPosition()
        ToolRotation.OnMouseLeftDown(self._handle, x, y)
        
        cmdList = []
        for ref in SCENE_EDITOR._selectedObjectRefList:
            node = ref()
            if not node:
                continue
                
            x, y, z, w = Transformation.GetRelativeRotation(SceneNode._CTransformation(node.GetCoreHandle()))
            cmdList.append(CCmdRotation(nodeRef = ref, newRotation = (x, y, z, w)))
            
        cmd = CCmdGroupCommand(cmdList = cmdList)
        HISTORY_MANAGER.RunCommand(cmd)
        
        self._groupCmdRef = HISTORY_MANAGER.GetCurrentCmdRef()
        self._yaw, self._pitch, self._roll = ToolRotation.GetRotation(self._handle)
        
    def OnMouseLeftUp(self, e):
        x, y = e.GetPosition()
        ToolRotation.OnMouseLeftUp(self._handle, x, y)
        
        self._yaw = 0
        self._pitch = 0
        self._roll = 0
        self._groupCmdRef = None        
        
    def OnMouseMotion(self, e):        
        x, y = e.GetPosition()
        ToolRotation.OnMouseMove(self._handle, x, y)        

__builtins__['ROTATION_TOOL'] = CRotationTool()
